package com.itlong.cloud.property.service.impl;


import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.property.PropertyAutoWithdrawDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyWithdrawGetDTO;
import com.itlong.cloud.POJO.PO.OperateTransferPropertyPO;
import com.itlong.cloud.POJO.PO.PropertyAutoWithdrawCashSetInfoPO;
import com.itlong.cloud.POJO.VO.operate.OperateBankCardVO;
import com.itlong.cloud.POJO.VO.property.PropertyBalanceVO;
import com.itlong.cloud.POJO.VO.property.PropertyProjectAmountVO;
import com.itlong.cloud.POJO.VO.property.PropertyWithdrawVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.commons.dao.IUpdateAmountDao;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.ChinaPayTradeStatusEnum;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.IsTimeoutEnum;
import com.itlong.cloud.operate.dao.IOperateBankCardManageDao;
import com.itlong.cloud.property.dao.IPropertyWithdrawDao;
import com.itlong.cloud.property.service.IPropertyWithdrawService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

/**
 * <desc>
 *      物业-提现服务-提现管理接口实现类
 * </desc>
 *
 * @createDate 2018/09/21
 */
@Service
public class PropertyWithdrawServiceImpl implements IPropertyWithdrawService {

    @Autowired
    IPropertyWithdrawDao iPropertyWithdrawDao;

    @Autowired
    IUpdateAmountDao iUpdateAmountDao;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    IOperateBankCardManageDao iOperateBankCardManageDao;

    /**
     * <desc>
     *      物业提现信息分页查询
     * <desc/>
     *
     * @param propertyAccountGetDTO 分页查询参数
     * @return
     * @author Qiang.S
     * @createDate 2018-09-21
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Page<PropertyWithdrawVO> getWithdrawByPage(PropertyWithdrawGetDTO propertyAccountGetDTO) throws Exception {
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(propertyAccountGetDTO);
        //分页类默认pageSize为20
        Page<PropertyWithdrawVO> page=new Page<>();
        page.getPage().setPageSize(propertyAccountGetDTO.getPageSize());
        page.getPage().setCurrentPage(propertyAccountGetDTO.getCurrentPage());
        params.put("projectId",propertyAccountGetDTO.getProjectId());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        //填充返回数据集
        List<PropertyWithdrawVO> list = iPropertyWithdrawDao.getWithdrawByPage(params);
        List<PropertyWithdrawVO> listAfter = new ArrayList<>();
        //替换银行卡号 处理只显示最后4位
        for (PropertyWithdrawVO propertyWithdrawVO:list) {
            if (propertyWithdrawVO.getBankCardNo() != null && propertyWithdrawVO.getBankCardNo().length() >= 4) {
                String replaceStr = "";
                for (int i=0 ;i<propertyWithdrawVO.getBankCardNo().length()-4;i++) {
                    replaceStr+="*";
                }
                propertyWithdrawVO.setBankCardNo(replaceStr+propertyWithdrawVO.getBankCardNo().substring(
                        propertyWithdrawVO.getBankCardNo().length()-4,propertyWithdrawVO.getBankCardNo().length()));
            }
            listAfter.add(propertyWithdrawVO);
        }
        //填充返回数据集
        page.setRows(listAfter, iPropertyWithdrawDao.getWithdrawInfoPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      查询可提现余额
     * <desc/>
     *
     * @param projectId 项目编号
     * @return PropertyBalanceVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyBalanceVO getBalance(String projectId) throws Exception {
        String allowedAashWithdrawl = iPropertyWithdrawDao.getBalance(projectId);
        List<PropertyBalanceVO> list = iPropertyWithdrawDao.getThirdPartyPaymentInfo();
        if (list.size() == 0 && allowedAashWithdrawl == null) {
            return null;
        }
        PropertyBalanceVO result = this.getThirdPartyPaymentInfo();
        result.setFinanceStatus(iPropertyWithdrawDao.getFinanceStatusByProjectId(projectId));
        result.setAllowedAashWithdrawl(allowedAashWithdrawl);
        return result;
    }

    /**
     * <desc>
     *      查询第三方手续费
     * <desc/>
     *
     * @return PropertyBalanceVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/10/31
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyBalanceVO getThirdPartyPaymentInfo() throws Exception {
        List<PropertyBalanceVO> list = iPropertyWithdrawDao.getThirdPartyPaymentInfo();
        if (list.size() == 0) {
            return null;
        }
        PropertyBalanceVO result = new PropertyBalanceVO();
        for (PropertyBalanceVO propertyBalanceVO : list) {
            //微信支付
            if (propertyBalanceVO.getThirdPartyPayment() != null && "1".equals(propertyBalanceVO.getThirdPartyPayment())) {
                result.setWechatHandlingFee(propertyBalanceVO.getHandlingFee());
                result.setLowAmount(propertyBalanceVO.getLowAmount());
            }
            //银联支付
            if (propertyBalanceVO.getThirdPartyPayment() != null && "2".equals(propertyBalanceVO.getThirdPartyPayment())) {
                result.setUnionpayHandlingFee(propertyBalanceVO.getHandlingFee());
                result.setLowAmount(propertyBalanceVO.getLowAmount());
            }
            //旺龙手续费
            if (propertyBalanceVO.getThirdPartyPayment() != null && "3".equals(propertyBalanceVO.getThirdPartyPayment())) {
                result.setWechatHandlingFee(propertyBalanceVO.getTakeHandlingFee());
                result.setUnionpayHandlingFee(propertyBalanceVO.getPayHandlingFee());
                result.setLowAmount(propertyBalanceVO.getLowAmount());
                break;
            }
        }
        return result;
    }

    /**
     * <desc>
     *      判断支付密码是否正确
     * <desc/>
     *
     * @param projectId 项目编号
     * @param payPassword 支付密码
     * @return PropertyBalanceVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer checkPayPassword(String projectId, String payPassword) throws Exception {
        return iPropertyWithdrawDao.checkPayPassword(projectId,payPassword);
    }

    /**
     * <desc>
     *      判断第三方支付中银联状态是否正常
     * <desc/>
     *
     * @return Integer
     * @author Qiang.S
     * @createDate 2018/10/09
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer checkUnionpayStatus() throws Exception {
        return iPropertyWithdrawDao.checkUnionpayStatus();
    }

    /**
     * <desc>
     *      自动提现设置
     * <desc/>
     *
     * @param propertyAutoWithdrawDTO 自动提现信息
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/23
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public Integer setAutoWithdraw(PropertyAutoWithdrawDTO propertyAutoWithdrawDTO) throws Exception {
        PropertyAutoWithdrawCashSetInfoPO propertyAutoWithdrawCashSetInfoPO = new PropertyAutoWithdrawCashSetInfoPO();
        BeanUtils.copyProperties(propertyAutoWithdrawDTO, propertyAutoWithdrawCashSetInfoPO);

        if (propertyAutoWithdrawDTO.getSetId() == null || "".equals(propertyAutoWithdrawDTO.getSetId())){
            Date createTime = new Date();
            propertyAutoWithdrawCashSetInfoPO.setSetId(LogicIdUtil.bussinessId());
            propertyAutoWithdrawCashSetInfoPO.setAmount(new BigDecimal(propertyAutoWithdrawDTO.getAmount()));
            propertyAutoWithdrawCashSetInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
            propertyAutoWithdrawCashSetInfoPO.setCreateTime(createTime);
            propertyAutoWithdrawCashSetInfoPO.setUpdateTime(null);
            propertyAutoWithdrawCashSetInfoPO.setOperatorUserId(propertyAutoWithdrawDTO.getLoginUserId());
            Map<String, Object> params = SqlUtil.durableData(propertyAutoWithdrawCashSetInfoPO, PlatformConstants.TABLE_SAVE);
            for(String key : params.keySet()){
                if (params.get(key) != null && "".equals(params.get(key))) {
                    params.put(key,null);
                }
            }
            return iPropertyWithdrawDao.setAutoWithdraw(params);
        }
        else{
            Date updateTime = new Date();
            propertyAutoWithdrawCashSetInfoPO.setAmount(new BigDecimal(propertyAutoWithdrawDTO.getAmount()));
            propertyAutoWithdrawCashSetInfoPO.setUpdateTime(updateTime);
            propertyAutoWithdrawCashSetInfoPO.setOperatorUserId(propertyAutoWithdrawDTO.getLoginUserId());
            Map<String, Object> params = SqlUtil.durableData(propertyAutoWithdrawCashSetInfoPO, PlatformConstants.TABLE_UPDATE);
            for(String key : params.keySet()){
                if (params.get(key) != null && "".equals(params.get(key))) {
                    params.put(key,null);
                }
            }
            return iPropertyWithdrawDao.updateAutoWithdraw(params);
        }
    }

    /**
     * <desc>
     *      查询项目可提现金额
     * <desc/>
     *
     * @param projectId 项目编号
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/24
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyProjectAmountVO getProjectAmountInfo(String projectId) throws Exception {
        return iUpdateAmountDao.getProjectAmountInfo(projectId);
    }

    /**
     * <desc>
     *      查询自动提现信息
     * <desc/>
     *
     * @param projectId 项目编号
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/24
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public PropertyAutoWithdrawCashSetInfoPO getAutoWithdraw(String projectId) throws Exception {
        return iPropertyWithdrawDao.getAutoWithdraw(projectId);
    }

    /**
     * <desc>
     *      查询项目财务状态
     * <desc/>
     *
     * @param projectId 项目编号
     * @return
     * @author Qiang.S
     * @createDate 2018/10/24
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public String getFinanceStatusByProjectId(String projectId) throws Exception {
        return iPropertyWithdrawDao.getFinanceStatusByProjectId(projectId);
    }

    /**
     * <desc>
     *      提现
     * <desc/>
     *
     * @param projectId 项目编号
     * @param bankCardId 银行卡ID
     * @param amount 提现金额
     * @param loginUserId 操作人ID
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/24
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public BigDecimal withdraw(String projectId, String bankCardId,String amount,String loginUserId) throws Exception {
        PropertyBalanceVO propertyBalanceVO = this.getBalance(projectId);
        if (propertyBalanceVO == null) {
            return new BigDecimal("-1");
        }
        OperateBankCardVO operateBankCardVO = iOperateBankCardManageDao.getCardInfo(bankCardId);
        OperateTransferPropertyPO operateTransferPropertyPO = new OperateTransferPropertyPO();
        Date createTime = new Date();
        int machineId = 1;
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if(hashCodeV < 0) {//有可能是负数
            hashCodeV = - hashCodeV;
        }
        //获取项目金额
        PropertyProjectAmountVO propertyProjectAmountVO = iUpdateAmountDao.getProjectAmountInfo(projectId);
        //计算并保存实时账户余额和交易后实时账户余额
        BigDecimal accountAmountBefore = new BigDecimal("0.00");//提现前
        if (propertyProjectAmountVO != null && propertyProjectAmountVO.getAccountAmount() != null && !"".equals(propertyProjectAmountVO.getAccountAmount())) {
            accountAmountBefore = new BigDecimal(propertyProjectAmountVO.getAccountAmount());
        }
        BigDecimal accountAmountAfter = accountAmountBefore.subtract(new BigDecimal(amount));//提现后
        operateTransferPropertyPO.setTradeBeforeAmount(accountAmountBefore);
        operateTransferPropertyPO.setTradeAfterAmount(accountAmountAfter);
        BigDecimal amountBigDecimal = new BigDecimal(amount);
        BigDecimal handlingFeeBigDecimal = new BigDecimal(propertyBalanceVO.getUnionpayHandlingFee());//手续费只保留银联手续费
        operateTransferPropertyPO.setCashId(machineId + String.format("%015d", hashCodeV));//16位
        operateTransferPropertyPO.setProjectId(projectId);
        operateTransferPropertyPO.setAmount(amountBigDecimal);
        //处理保留2位
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);//四舍五入
        operateTransferPropertyPO.setHandlingFee(new BigDecimal(decimalFormat.format(handlingFeeBigDecimal)));//保留2位小数
        operateTransferPropertyPO.setBankCardId(bankCardId);
        operateTransferPropertyPO.setBankCardNo(operateBankCardVO.getBankCardNo());
        operateTransferPropertyPO.setOpenBankName(operateBankCardVO.getOpenBankName());
        operateTransferPropertyPO.setTradeStatus(ChinaPayTradeStatusEnum.ALREADY_SUBMITTED.getType());
        operateTransferPropertyPO.setOperatorUserId(loginUserId);
        operateTransferPropertyPO.setIsTimeout(IsTimeoutEnum.UN_TIME_OUT.getType());
        operateTransferPropertyPO.setStatus(DataStatusEnum.NORMAL.getType());
        operateTransferPropertyPO.setCreateTime(createTime);
        operateTransferPropertyPO.setUpdateTime(null);

        Map<String, Object> params = SqlUtil.durableData(operateTransferPropertyPO, PlatformConstants.TABLE_SAVE);
        for(String key : params.keySet()){
            if (params.get(key) != null && "".equals(params.get(key))) {
                params.put(key,null);
            }
        }
        //更新项目可提现金额,实时金额
        Map<String,Object> map=new HashMap<>();
        map.put("arithmeticFlag", "1");//运算: 0加,1减
        map.put("amount", amountBigDecimal);//金额
        map.put("projectId", projectId);//项目编号
        map.put("updateNameFlag","");//0可提现余额,1实时余额   为空都更新

        messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_MANAGER_QUEUE, JSON.toJSONString(map),
                RabbitMQConstant.RABBITMQ_PAY_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_ROUTING_KEY);
        iPropertyWithdrawDao.withdraw(params);
        return operateTransferPropertyPO.getHandlingFee();
    }

    /**
     * <desc>
     *      自动提现
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2018/09/26
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void doAutoWithdraw() throws Exception {
        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        //查询出所有自动提现信息
        List<PropertyAutoWithdrawCashSetInfoPO> list = iPropertyWithdrawDao.getAutoWithdrawAll();
        //循环处理所有自动提现请求
        for (PropertyAutoWithdrawCashSetInfoPO propertyAutoWithdrawCashSetInfoPO : list) {
            //查询项目余额
            PropertyProjectAmountVO propertyProjectAmountVO = iUpdateAmountDao.getProjectAmountInfo(propertyAutoWithdrawCashSetInfoPO.getProjectId());
            if (("2".equals(propertyAutoWithdrawCashSetInfoPO.getCashRule()) && day == Integer.parseInt(propertyAutoWithdrawCashSetInfoPO.getRuleDate()))
                    || "3".equals(propertyAutoWithdrawCashSetInfoPO.getCashRule())) {//按月当前日,或者按天
                //判断当前可提现金额是否大于设置金额
                if (propertyProjectAmountVO != null && !StringUtils.isBlank(propertyProjectAmountVO.getAllowedCashWithdrawl())
                        && new BigDecimal(propertyProjectAmountVO.getAllowedCashWithdrawl()).compareTo(propertyAutoWithdrawCashSetInfoPO.getAmount()) != -1) {
                    this.withdraw(propertyAutoWithdrawCashSetInfoPO.getProjectId(), propertyAutoWithdrawCashSetInfoPO.getBankCardId(), propertyProjectAmountVO.getAccountAmount(), propertyAutoWithdrawCashSetInfoPO.getOperatorUserId());
                }
            }
        }
    }

}
